/*
 * CMovimentavel.cpp
 *
 *  Created on: 27/08/2008
 *      Author: samuel.grigolato
 */

#include "CMovimentavel.h"
#include "../CParametros.h"

CMovimentavel::CMovimentavel() {
	VelocidadeX = 0;
	VelocidadeY = 0;
	UltimaMovimentacao = 0;
	FatorVelocidade = 0;
	FatorPatins = 0;
	TileX = 0;
	TileY = 0;
	MovBaixo = false;
	MovCima = false;
	MovDireita = false;
	MovEsquerda = false;
}

CMovimentavel::~CMovimentavel() {
	//
}

void CMovimentavel::OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode) {
	switch (sym) {
	case SDLK_UP:
		MovCima = true;
		break;
	case SDLK_DOWN:
		MovBaixo = true;
		break;
	case SDLK_LEFT:
		MovEsquerda = true;
		break;
	case SDLK_RIGHT:
		MovDireita = true;
		break;
	default:
		break;
	}
}

void CMovimentavel::OnKeyUp(SDLKey sym, SDLMod mod, Uint16 unicode) {
	switch (sym) {
	case SDLK_UP:
		MovCima = false;
		break;
	case SDLK_DOWN:
		MovBaixo = false;
		break;
	case SDLK_LEFT:
		MovEsquerda = false;
		break;
	case SDLK_RIGHT:
		MovDireita = false;
		break;
	default:
		break;
	}
}

void CMovimentavel::OnLoop() {
	long ticks = SDL_GetTicks();
	if (ticks - UltimaMovimentacao > 17 - FatorPatins) {
		UltimaMovimentacao = ticks;
		AtualizaVelocidade();
		CorrigeMovimentacao();
		X += VelocidadeX;
		Y += VelocidadeY;
		AtualizaAnimState();
		CEntity::OnLoop();
		AtualizaPosicao();
	}
}

void CMovimentavel::AtualizaVelocidade() {
	VelocidadeX = 0;
	VelocidadeY = 0;
	if (MovBaixo) {
		VelocidadeY += FatorVelocidade;
	}
	if (MovCima) {
		VelocidadeY -= FatorVelocidade;
	}
	if (MovDireita) {
		VelocidadeX += FatorVelocidade;
	}
	if (MovEsquerda) {
		VelocidadeX -= FatorVelocidade;
	}
}

void CMovimentavel::ProcessaResultadoColisao(CResultadoColisao Resultado) {
	if (Resultado.ColidiuA && VelocidadeY > 0) {
		VelocidadeX = RecuperaPropVelocidadeX(Resultado);
		VelocidadeY = 0;
	}
	if (Resultado.ColidiuB && VelocidadeX < 0) {
		VelocidadeY = RecuperaPropVelocidadeY(Resultado);
		VelocidadeX = 0;
	}
	if (Resultado.ColidiuC && VelocidadeY < 0) {
		VelocidadeX = RecuperaPropVelocidadeX(Resultado);
		VelocidadeY = 0;
	}
	if (Resultado.ColidiuD && VelocidadeX > 0) {
		VelocidadeY = RecuperaPropVelocidadeY(Resultado);
		VelocidadeX = 0;
	}
}

void CMovimentavel::AtualizaAnimState() {
	AnimState = 4;
	if (MovBaixo) {
		AnimState = 0;
	}
	if (MovCima) {
		AnimState = 1;
	}
	if (MovDireita) {
		AnimState = 2;
	}
	if (MovEsquerda) {
		AnimState = 3;
	}
}

void CMovimentavel::AtualizaPosicao() {
	int LarguraTela = CParametros::GetLarguraJanela();
	int AlturaTela = CParametros::GetAlturaJanela();
	int LarguraTile = CParametros::GetLarguraTile();
	int AlturaTile = CParametros::GetAlturaTile();

	int BackgroundX = (LarguraTela - (LarguraTile
			* CParametros::GetLarguraMapa())) / 2;
	int BackgroundY =
			(AlturaTela - (AlturaTile * CParametros::GetAlturaMapa())) / 2;
	TileX = ((X + (Width / 2)) - BackgroundX) / LarguraTile;
	TileY = (int) ((Y + (Height * 0.8)) - BackgroundY) / AlturaTile;
}

void CMovimentavel::CorrigeMovimentacao() {
	int LarguraTela = CParametros::GetLarguraJanela();
	int AlturaTela = CParametros::GetAlturaJanela();
	int LarguraTile = CParametros::GetLarguraTile();
	int AlturaTile = CParametros::GetAlturaTile();

	int NovaPosicaoX = X + VelocidadeX + Width;
	int NovaPosicaoY = Y + VelocidadeY + Height;

	int BackgroundX = (LarguraTela - (LarguraTile
			* CParametros::GetLarguraMapa())) / 2;
	int BackgroundY =
			(AlturaTela - (AlturaTile * CParametros::GetAlturaMapa())) / 2;

	CRetangulo RetEnt = GetRetangulo();
	RetEnt.A += VelocidadeY;
	RetEnt.C += VelocidadeY;
	RetEnt.B += VelocidadeX;
	RetEnt.D += VelocidadeX;

	CResultadoColisao Resultado = CEntity::VerificaColisoes(RetEnt, this);

	if ((NovaPosicaoX - LarguraTile) < BackgroundX || NovaPosicaoX
			> (BackgroundX + (LarguraTile * CParametros::GetLarguraMapa()))) {
		VelocidadeX = 0;
	}
	if ((NovaPosicaoY - AlturaTile) < BackgroundY || NovaPosicaoY
			> (BackgroundY + (AlturaTile * CParametros::GetAlturaMapa()))) {
		VelocidadeY = 0;
	}

	ProcessaResultadoColisao(Resultado);

}

int CMovimentavel::RecuperaPropVelocidadeY(CResultadoColisao Resultado) {
	if (VelocidadeY == 0) {
		int AlturaTela = CParametros::GetAlturaJanela();
		int AlturaTile = CParametros::GetAlturaTile();

		int BackgroundY =
				(AlturaTela - (AlturaTile * CParametros::GetAlturaMapa())) / 2;
		CRetangulo Ret = GetRetangulo();

		if (Ret.C < BackgroundY + (Resultado.TileY * AlturaTile + (AlturaTile * 0.18))) {
			return - 1;
		}
		if (Ret.A > BackgroundY + (Resultado.TileY * AlturaTile + (AlturaTile * 0.82))) {
			return 1;
		}
		return 0;
	} else {
		return VelocidadeY;
	}
}

int CMovimentavel::RecuperaPropVelocidadeX(CResultadoColisao Resultado) {
	if (VelocidadeX == 0) {
		int LarguraTela = CParametros::GetLarguraJanela();
		int LarguraTile = CParametros::GetLarguraTile();

		int BackgroundX = (LarguraTela - (LarguraTile
				* CParametros::GetLarguraMapa())) / 2;
		CRetangulo Ret = GetRetangulo();

		if (Ret.B < BackgroundX + (Resultado.TileX * LarguraTile + (LarguraTile * 0.40))) {
			return - 1;
		}
		if (Ret.D > BackgroundX + (Resultado.TileX * LarguraTile + (LarguraTile * 0.60))) {
			return 1;
		}
		return 0;
	} else {
		return VelocidadeX;
	}
}

void CMovimentavel::ProcessaColisao() {
	//
}

